package com.pkk.cloud.support.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pkk.cloud.support.admin.dto.req.user.OauthBindUserClientReqDto;
import com.pkk.cloud.support.admin.dto.req.user.OauthUserAddReqDto;
import com.pkk.cloud.support.admin.dto.req.user.OauthUserIdReqDto;
import com.pkk.cloud.support.admin.dto.req.user.OauthUserQueryPageReqDto;
import com.pkk.cloud.support.admin.dto.req.user.OauthUserUpdateReqDto;
import com.pkk.cloud.support.admin.dto.resp.user.OauthChildUserClientRespDto;
import com.pkk.cloud.support.admin.dto.resp.user.OauthSysUserDetailRespDto;
import com.pkk.cloud.support.admin.dto.resp.user.OauthSysUserQueryPageRespDto;
import com.pkk.cloud.support.admin.dto.resp.user.OauthUserClientRespDto;
import com.pkk.cloud.support.admin.entity.resource.PenguinSysUserRole;
import com.pkk.cloud.support.admin.entity.user.PenguinSysUser;
import com.pkk.cloud.support.admin.mybatis.user.PenguinSysUserMapper;
import com.pkk.cloud.support.admin.oauth2.api.common.resp.PenguinSysUserInfo;
import com.pkk.cloud.support.admin.service.PenguinSysClientScopeBusinessService;
import com.pkk.cloud.support.admin.service.PenguinSysUserRoleService;
import com.pkk.cloud.support.admin.service.PenguinSysUserService;
import com.pkk.cloud.support.oauth2.client.detail.client.entity.PenguinOauthClient;
import com.pkk.cloud.support.oauth2.client.detail.client.service.PenguinOauthClientService;
import com.pkk.components.rpc.page.Page;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @description: 系统用户业务类
 * @author: peikunkun
 * @create: 2020-03-06 15:20
 **/
@Slf4j
@Service
public class PenguinSysUserServiceImpl extends ServiceImpl<PenguinSysUserMapper, PenguinSysUser> implements
    PenguinSysUserService {

  @Resource
  private PenguinSysUserRoleService penguinSysUserRoleService;
  @Resource
  private PenguinSysClientScopeBusinessService penguinSysClientScopeBusinessService;

  /**
   * @Description: 依据id查询系统用户信息
   * @Param: id
   * @return: com.pkk.cloud.support.admin.entity.user.PenguinSysUser
   * @Author: peikunkun
   * @Date: 2020/3/6 0006 下午 5:19
   */
  public PenguinSysUser getSysUserId(Long id) {
    return this.getById(id);
  }


  /**
   * @Description: 获取用户信息依据名称和客户端id
   * @Param: username
   * @Param clientId
   * @return: com.pkk.cloud.support.admin.oauth.api.common.resp.PenguinSysUser
   * @Author: peikunkun
   * @Date: 2020/3/18 0018 下午 6:03
   */
  @Override
  public PenguinSysUserInfo findPenguinUserByNameAndClientId(
      String username, String clientId) {
    final PenguinSysUser sysUser = this.findPenguinUserByUsernameAndClientId(username, clientId);
    if (null != sysUser) {
      return PenguinSysUserInfo.builder()
          .id(sysUser.getId().toString()).username(sysUser.getUname())
          .password(sysUser.getPwd()).enabled(sysUser.getIsEnable())
          .accountNonExpired(true).accountNonLocked(sysUser.getIsEnable())
          .credentialsNonExpired(true)
          .build();
    } else {
      return null;
    }
  }


  /**
   * @Description: 依据用户和客户端id查询系统用户信息
   * @Param: username
   * @Param clientId
   * @return: com.pkk.cloud.support.admin.entity.user.PenguinSysUser
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 上午 9:26
   */
  public PenguinSysUser findPenguinUserByUsernameAndClientId(String username, String clientId) {
    final HashMap<String, String> param = new HashMap<>(3);
    param.put("username", username);
    param.put("clientId", clientId);
    return baseMapper.findPenguinUserByNameAndClientId(param);
  }

  /**
   * @Description: 保存系统用户
   * @Param: user
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 上午 9:23
   */
  @Override
  public boolean saveSysUser(OauthUserAddReqDto userAddReqDto,String userId) {
    final PenguinSysUser user = new PenguinSysUser();
    BeanUtils.copyProperties(userAddReqDto, user);
    user.setCreateTime(new Date());
    user.setCreateName(userId);

    //角色关系重新绑定
    if (null != userAddReqDto.getRoles()) {
      final ArrayList<PenguinSysUserRole> penguinSysUserRoles = new ArrayList<>();
      userAddReqDto.getRoles().stream().forEach(r -> {
        penguinSysUserRoles.add(PenguinSysUserRole.builder().userId(user.getId()).roleId(r).build());
      });
      if (null != penguinSysUserRoles && penguinSysUserRoles.size() > 0) {
        penguinSysUserRoleService.saveBatch(penguinSysUserRoles);
      }
    }
    return baseMapper.insert(user) == 1;
  }

  /**
   * @Description: 删除系统用户依据id
   * @Param: id
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 上午 9:28
   */
  @Override
  @Transactional
  public boolean delSysUserById(Long[] ids) {
    for (int i = 0; i < ids.length; i++) {
      baseMapper.updateById(PenguinSysUser.builder().updateTime(new Date()).isEnable(false).id(ids[i]).build());
    }
    return true;
  }

  /**
   * @Description: 更新用户信息依据id
   * @Param: user
   * @return: boolean
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 上午 10:12
   */
  @Override
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public boolean updateSysUserById(OauthUserUpdateReqDto reqDto) {
    final PenguinSysUser user = new PenguinSysUser();
    BeanUtils.copyProperties(reqDto, user);
    user.setUpdateTime(new Date());

    //角色关系重新绑定
    if (null != reqDto.getRoles()) {
      final ArrayList<PenguinSysUserRole> penguinSysUserRoles = new ArrayList<>();
      reqDto.getRoles().stream().forEach(r -> {
        penguinSysUserRoles.add(PenguinSysUserRole.builder().userId(user.getId()).roleId(r).build());
      });
      penguinSysUserRoleService.remove(new UpdateWrapper<PenguinSysUserRole>().eq("user_id", user.getId()));
      if (null != penguinSysUserRoles && penguinSysUserRoles.size() > 0) {
        penguinSysUserRoleService.saveBatch(penguinSysUserRoles);
      }
    }
    return baseMapper.updateById(user) == 1;
  }

  /**
   * @Description: 获取系统用户分页列表
   * @Param: body
   * @return: java.util.List<com.pkk.cloud.support.admin.dto.resp.user.OauthSysUserQueryPageRespDto>
   * @Author: peikunkun
   * @Date: 2020/4/2 0002 上午 10:59
   */
  @Override
  public PageInfo<OauthSysUserQueryPageRespDto> findSysUserPageList(Page page, OauthUserQueryPageReqDto body) {
    PageHelper.startPage(page.getPageIndex(), page.getPageSize());
    return new PageInfo<OauthSysUserQueryPageRespDto>(baseMapper.findSysUserPageList(body));
  }


  /**
   * @Description: 获取用户信息依据id
   * @Param: body
   * @return: com.pkk.cloud.support.admin.dto.resp.user.OauthSysUserDetailRespDto
   * @Author: peikunkun
   * @Date: 2020/4/6 0006 上午 10:18
   */
  @Override
  public OauthSysUserDetailRespDto findUserById(OauthUserIdReqDto body) {
    final PenguinSysUser user = baseMapper.selectById(body.getId());
    OauthSysUserDetailRespDto userDetailRespDto = new OauthSysUserDetailRespDto();
    BeanUtils.copyProperties(user, userDetailRespDto);

    //获取的角色信息
    final List<PenguinSysUserRole> userRoles = penguinSysUserRoleService
        .list(new QueryWrapper<PenguinSysUserRole>().eq("user_id", body.getId()));
    if (null != userRoles && userRoles.size() > 0) {
      userDetailRespDto.setRoles(userRoles.stream().map(PenguinSysUserRole::getRoleId).collect(Collectors.toList()));
    }
    return userDetailRespDto;
  }


  /**
   * @Description: 获取用户客户段信息依据用户id
   * @Param: body
   * @return: com.pkk.cloud.support.admin.dto.resp.user.OauthUserClientRespDto
   * @Author: peikunkun
   * @Date: 2020/4/8 下午9:44
   */
  @Override
  public OauthUserClientRespDto findUserClientByUserId(OauthUserIdReqDto body) {
    //全部的客户端
    List<PenguinOauthClient> clientsInfo=penguinSysClientScopeBusinessService.findAllClientView();
    List<OauthChildUserClientRespDto> clients=new ArrayList<>();
    if(null!=clientsInfo&&clientsInfo.size()>0){
      clientsInfo.stream().forEach(c->{
        clients.add(OauthChildUserClientRespDto.builder().id(c.getId()).clientName(c.getClientName()).clientId(c.getClientId()).build());
      });
    }

    //用户绑定的客户端
    List<PenguinOauthClient> clientsUser=penguinSysClientScopeBusinessService.findUserClientView(body.getId());
    final List<String> bindClientId = clientsUser.stream().map(PenguinOauthClient::getClientId).collect(Collectors.toList());
    return OauthUserClientRespDto.builder().clients(clients).clientIds(bindClientId).build();
  }

  /**
   * @Description: 绑定用户与访问客户端的信息
   * @Param: request
   * @return: com.pkk.components.rpc.response.CommonResponse<java.lang.Boolean>
   * @Author: peikunkun
   * @Date: 2020/4/8 下午10:05
   */
  @Override
  public boolean bindUserClient(OauthBindUserClientReqDto body) {
    //删除客户端绑定
    baseMapper.removeUserClientBind(body.getUserId());
    if(null!=body.getClientIds()&&body.getClientIds().size()>0){
      baseMapper.bindUserClient(body);
    }
    return true;
  }
}
